home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 4
/
Amiga Tools 4.iso
/
tools
/
disk-tools
/
cd-rom
/
audio
/
jukebox
/
jukebox-extensions
/
source
/
catviewer.c
next >
Wrap
C/C++ Source or Header
|
1996-02-26
|
18KB
|
706 lines
/* JB-CatViewer -- soll die JukeBox Katalogdateien komfortabler anzeigen */
/* INCLUDE */
#include <exec/lists.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <clib/alib_protos.h>
#if defined(_DCC)
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#else
#include <proto/intuition.h>
#include <proto/graphics.h>
#if defined(__GNUC__)
#define GT_SetGadgetAttrsA _GT_SetGadgetAttrsA
#endif
#include <proto/gadtools.h>
#if defined(__GNUC__)
#undef GT_SetGadgetAttrsA
#endif
#include <proto/exec.h>
#include <proto/dos.h>
#endif
#include <string.h>
struct VolNode {
struct Node ExecNode;
UBYTE Pad[2];
struct MinList TitleHeader;
};
struct FindPara {
BYTE Success,Pad[3];
LONG Position;
};
/* P R O T O T Y P E N */
void AdjustGadgets(void);
int MakeGadgets(void);
void RemoveGadgets(void);
int MakeLists(void);
void CatchNextString(char *,LONG,struct FindPara *);
struct VolNode *MakeVolNode(char *);
struct Node *MakeNode(char *);
struct MinList *TitleHeaderOfNthVolNode(int);
void FindStr(char *,char *,struct FindPara *);
int CompareFrag(char *,char *);
void ShowMsg(STRPTR);
void Search(int,char *);
void SearchMessage(char *,char *);
/*
** NewList als Makro
*/
/* DEFINES */
/*
#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
(l)->lh_Tail = NULL, \
(l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
*/ /* deaktiviert, benutzt amiga.lib NewList! */
#define SEARCHLEN 50
#define NOTHINGFOUND 0
#define STRINGFOUND 1
#define CROSSFOUND 2
#define FROMTOP 0
#define CONTINUE 1
#define INIT 2
#define POOLSIZE 4096
#define TRESHSIZE 1024
#define DEFAULTIN "musiccatalog.cat"
#define DEFAULTLEFT "CD"
#define DEFAULTRIGHT "Titel"
#define DEFAULTSEARCH "weitersuchen"
#define DEFAULTFOUND "Text gefunden!"
#define NOMEM "Not enough memory!\n"
#define ARGSPATTERN "INFILE,LEFTTEXT,RIGHTTEXT,SEARCHTEXT,FOUNDTEXT"
/* Globale Variablen und Strukturen */
const char VERSION[]="$VER: JukeBox-CatView V1.03 by P. Kursawe 1996";
/* libnix specials */
int __nocommandline = 1;
int __initlibraries = 1;
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase=NULL;
struct DosLibrary *DOSBase= NULL;
struct Gadget *gg1ptr = NULL;
struct Gadget *gg2ptr = NULL;
struct Gadget *gg4ptr = NULL;
struct Gadget *gg3ptr = NULL;
struct Gadget *glistptr = NULL;
struct Gadget *context = NULL;
struct VisualInfo *vi = NULL;
struct Gadget *dummygg = NULL;
struct Window *mywindow = NULL;
struct MinList Header;
APTR mempool;
struct RDArgs *rdargs = NULL;
ULONG Kommandoparameter[] = {
(ULONG)DEFAULTIN,
(ULONG)DEFAULTLEFT,
(ULONG)DEFAULTRIGHT,
(ULONG)DEFAULTSEARCH,
(ULONG)DEFAULTFOUND
};
char searchstrbuf[SEARCHLEN] = "#?TEXT#?";
struct TagItem gg1tags[]={GTLV_Labels,0,GTLV_ShowSelected,TAG_DONE,0};
struct TagItem gg2tags[]={GTLV_Labels,0,GTLV_ReadOnly,TRUE,TAG_DONE,0};
struct TagItem gg3tags[]={GTST_String,(ULONG)&searchstrbuf,GTST_MaxChars,SEARCHLEN,TAG_DONE,0};
struct TextAttr normalfont;
struct NewGadget gadget1=
{
0,0,0,0,NULL,&normalfont,1,PLACETEXT_BELOW,0,0
};
struct NewGadget gadget2=
{
0,0,0,0,NULL,&normalfont,2,PLACETEXT_BELOW,0,0
};
struct NewGadget gadget4=
{
0,0,0,0,NULL,&normalfont,4,PLACETEXT_IN,0,0
};
struct NewGadget gadget3 =
{
0,0,0,0,NULL,&normalfont,3,0,0,0
};
int FontHeight;
struct StringInfo * strinf; /* Zwischenspeicher wegen Typecasting */
int main()
{
static struct TagItem wintags[]=
{
WA_Flags,WFLG_SIZEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE,
WA_Left,0,
WA_Top,15,
WA_MinWidth,400,
WA_MinHeight,115,
WA_MaxWidth,-1,
WA_MaxHeight,-1,
WA_Title,(ULONG)"JukeBox Catalog Viewer",
WA_Width,640,
WA_Height,184,
WA_IDCMP,IDCMP_CLOSEWINDOW|LISTVIEWIDCMP|IDCMP_NEWSIZE,
TAG_DONE,0
};
struct IntuiMessage *imsg;
struct Gadget *address;
ULONG imClass;
UWORD imCode;
if((mempool=LibCreatePool(MEMF_CLEAR,POOLSIZE,TRESHSIZE)) == NULL)
return;
NewList((struct List *)&Header);
if((DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37L)))
{
if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L)))
{
if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L)))
{
if((GadToolsBase=OpenLibrary("gadtools.library",37L)))
{
/* hier sind alle Libraries offen */
rdargs=ReadArgs(ARGSPATTERN,Kommandoparameter,NULL);
gadget1.ng_GadgetText=(UBYTE *)Kommandoparameter[1];
gadget2.ng_GadgetText=(UBYTE *)Kommandoparameter[2];
gadget4.ng_GadgetText=(UBYTE *)Kommandoparameter[3];
if((mywindow=OpenWindowTagList(NULL,wintags)))
{
/* Verzweifelter Versuch, den richtigen Font zu nehmen */
FontHeight = mywindow->IFont->tf_YSize;
normalfont.ta_YSize = FontHeight;
normalfont.ta_Name = mywindow->IFont->tf_Message.mn_Node.ln_Name;
normalfont.ta_Style = mywindow->IFont->tf_Style;
normalfont.ta_Flags = mywindow->IFont->tf_Flags;
/* daran ändert sich nix... */
gadget4.ng_Height = FontHeight+6;
gadget3.ng_Height = FontHeight+6;
gadget1.ng_LeftEdge = mywindow->BorderLeft+5;
gadget1.ng_TopEdge = mywindow->BorderTop+5;
gadget2.ng_TopEdge = gadget1.ng_TopEdge;
gadget3.ng_LeftEdge = gadget1.ng_LeftEdge;
AdjustGadgets();
if((MakeLists()))
{
if((MakeGadgets()))
{
Search(INIT,""); /* in C++ waere das schoener zu loesen... */
for(;;)
{
if(Wait(1L<<mywindow->UserPort->mp_SigBit|SIGBREAKF_CTRL_C)&SIGBREAKF_CTRL_C)
break;
while((imsg=GT_GetIMsg(mywindow->UserPort)) != NULL)
{
imClass = imsg->Class;
imCode = imsg->Code;
address = imsg->IAddress;
GT_ReplyIMsg(imsg);
strinf = (struct StringInfo *)gg3ptr->SpecialInfo; /*Wie sonst soll man den korrekt dereferenzieren? */
switch(imClass)
{
case IDCMP_CLOSEWINDOW:
goto ende;
case IDCMP_GADGETUP:
if(address->GadgetID==1)
{
gg2tags[0].ti_Data=(ULONG)TitleHeaderOfNthVolNode(imCode);
GT_SetGadgetAttrsA(gg2ptr,mywindow,NULL,gg2tags);
}
if(address->GadgetID==4)
{
Search(CONTINUE,(char *)strinf->Buffer);
}
if(address->GadgetID==3)
{
Search(FROMTOP,(char *)strinf->Buffer);
}
break;
case IDCMP_NEWSIZE:
strcpy(searchstrbuf,(char *)strinf->Buffer);
RemoveGadgets();
AdjustGadgets();
MakeGadgets();
default:
break;
}
}
}
ende:
RemoveGadgets();
}
else
{
ShowMsg("Could not allocate Gadgets.\n");
}
LibDeletePool(mempool);
}
else
{
ShowMsg("Could not build lists\n");
}
CloseWindow(mywindow);
}
FreeArgs(rdargs);
/* alle Libraries schließen */
CloseLibrary(GadToolsBase);
}
else
{
ShowMsg("Can't open gadtools.library V37.\n");
}
CloseLibrary((struct Library *)IntuitionBase);
}
else
{
ShowMsg("Can't open intuition.library V37.\n");
}
CloseLibrary((struct Library *)GfxBase);
}
else
{
ShowMsg("Can't open graphics.library V37.\n");
}
CloseLibrary((struct Library *)DOSBase);
}
return 0;
}
/* -------------------------------------- */
/* UNTERROUTINEN */
/* -------------------------------------- */
void AdjustGadgets(void)
{
gadget1.ng_Height = mywindow->Height - mywindow->BorderBottom - 2*FontHeight - 16 - gadget1.ng_TopEdge;
if(gadget1.ng_Height < 5)
{
gadget1.ng_Height = 5;
}
gadget1.ng_Width = ( (mywindow->Width - mywindow->BorderLeft - mywindow-> BorderRight - 15) / 2);
if(gadget1.ng_Width < 10)
{
gadget1.ng_Width = 10;
}
gadget2.ng_LeftEdge = gadget1.ng_Width + gadget1.ng_LeftEdge + 5;
gadget2.ng_Height = gadget1.ng_Height;
gadget2.ng_Width = gadget1.ng_Width;
gadget4.ng_TopEdge = gadget1.ng_TopEdge + gadget1.ng_Height + FontHeight + 5;
gadget4.ng_Width = 200; /* sollte reichen...*/
gadget4.ng_LeftEdge = gadget2.ng_LeftEdge + gadget2.ng_Width - gadget4.ng_Width;
gadget3.ng_TopEdge = gadget4.ng_TopEdge;
gadget3.ng_Width = gadget2.ng_LeftEdge + gadget2.ng_Width - gadget4.ng_Width - 5 - gadget3.ng_LeftEdge;
}
/* Muß hier Gadgets belegen und einbinden. */
int MakeGadgets(void)
{
int ret=FALSE;
if((vi=GetVisualInfoA(mywindow->WScreen,NULL)))
{
gadget1.ng_VisualInfo = vi;
gadget2.ng_VisualInfo = vi;
gadget4.ng_VisualInfo = vi;
gadget3.ng_VisualInfo = vi;
if((dummygg=CreateContext(&glistptr)))
{
if((gg1ptr=CreateGadgetA(LISTVIEW_KIND,dummygg,&gadget1,gg1tags)))
{
if((gg2ptr=CreateGadgetA(LISTVIEW_KIND,gg1ptr,&gadget2,gg2tags)))
{
if((gg4ptr=CreateGadgetA(BUTTON_KIND,gg2ptr,&gadget4,NULL)))
{
if((gg3ptr=CreateGadgetA(STRING_KIND,gg4ptr,&gadget3,gg3tags)))
{
ret=TRUE;
strinf = (struct StringInfo *)gg3ptr->SpecialInfo;
strcpy((char *)strinf->Buffer,searchstrbuf);
EraseRect(mywindow->RPort,mywindow->BorderLeft,mywindow->BorderTop,mywindow->Width-mywindow->BorderRight-1,mywindow->Height-mywindow->BorderBottom-1);
AddGList(mywindow,glistptr,-1,-1,0);
RefreshWindowFrame(mywindow);
GT_RefreshWindow(mywindow,0);
}
}
}
else
{
FreeGadgets(glistptr);
glistptr = NULL;
}
}
}
else
{
FreeVisualInfo(vi);
}
}
return(ret);
}
void RemoveGadgets(void)
{
if((glistptr))
{
RemoveGList(mywindow,glistptr,-1);
FreeGadgets(glistptr);
FreeVisualInfo(vi);
}
}
int MakeLists(void)
{
struct FileInfoBlock *fib = NULL;
struct VolNode *voln=NULL;
struct Node *node=NULL;
struct FindPara Paras;
BPTR filehandle = NULL;
BYTE *buffer;
int ret = FALSE;
LONG pos=0;
Paras.Success = CROSSFOUND; Paras.Position = 0;
if((fib=AllocDosObject(DOS_FIB,NULL)))
{
if((filehandle=Open((char *)Kommandoparameter[0],MODE_OLDFILE)))
{
if(DOSTRUE==ExamineFH(filehandle,fib))
{
if((buffer=LibAllocPooled(mempool,fib->fib_Size)))
{
Read(filehandle,buffer,fib->fib_Size);
/* Eigentliche Bearbeitung der Textdatei */
gg1tags[0].ti_Data=(ULONG)&Header;
while((Paras.Success != NOTHINGFOUND)&&((int)pos < (int)buffer + (int)fib->fib_Size))
{
pos=pos+Paras.Position;
switch(Paras.Success)
{
case STRINGFOUND:
pos=Paras.Position;
if((voln))
{
if((node=MakeNode(&buffer[pos])))
{
AddTail((struct List *)&voln->TitleHeader,node);
}
}
pos=pos+strlen(&buffer[pos]);
break;
case CROSSFOUND:
pos = pos + Paras.Position;
CatchNextString(buffer,pos,&Paras);
if(Paras.Success == STRINGFOUND)
{
pos=Paras.Position;
if((voln=MakeVolNode(&buffer[pos])))
{
AddTail((struct List *)&Header,&voln->ExecNode);
ret=TRUE;
}
pos=pos+strlen(&buffer[pos]);
}
break;
default:
break;
}
CatchNextString(buffer,pos,&Paras);
}
/* fertig.... */
LibFreePooled(mempool,buffer,fib->fib_Size);
}
else
{
ShowMsg(NOMEM);
}
}
else
{
ShowMsg("Examine failed.\n");
}
Close(filehandle);
}
else
{
ShowMsg("Could not open \"");
ShowMsg((char *)Kommandoparameter[0]);
ShowMsg("\".\n");
}
FreeDosObject(DOS_FIB,fib);
}
else
{
ShowMsg("Could not allocate FileInfoBlock.\n");
}
return(ret);
}
/* Sucht einen String */
void CatchNextString(char *Puffer,LONG position,struct FindPara *parameter)
{
LONG posbak=0;
FindStr(&Puffer[position],">=\"",parameter);
if(parameter->Success == STRINGFOUND)
{
parameter->Position=parameter->Position+3;
position= position + parameter->Position;
FindStr(&Puffer[position],"\"",parameter);
if(parameter->Success != NOTHINGFOUND)
{
while(parameter->Success==CROSSFOUND)
{
posbak=parameter->Position+posbak;
FindStr(&Puffer[posbak+position],"\"",parameter);
}
Puffer[position + parameter->Position+posbak]=0;
parameter->Position=position;
}
else
{
parameter->Success=NOTHINGFOUND;
}
}
}
/* Erzeugt Nodes mit Eintrag fuer Liste der Titel */
struct VolNode *MakeVolNode(char string[])
{
struct VolNode *mem;
if((mem=LibAllocPooled(mempool,sizeof(struct VolNode)+strlen(string)+1)))
{
mem->ExecNode.ln_Name=(char *)(mem+1);
NewList((struct List *)&mem->TitleHeader);
strcpy((char *)(mem+1),string);
}
else
{
ShowMsg(NOMEM);
}
return mem;
}
/* Erzeugt stinknormale Nodes (mit Name dahinter, natürlich! */
struct Node *MakeNode(char string[])
{
struct Node *mem;
if((mem=LibAllocPooled(mempool,sizeof(struct Node)+strlen(string)+1)))
{
mem->ln_Name=(char *)(mem+1);
strcpy((char *)(mem+1),string);
}
else
{
ShowMsg(NOMEM);
}
return(mem);
}
/* Gibt einen Zeiger auf den TitleHeader der n-ten VolNode zurück, NULL, falls leer! */
struct MinList *TitleHeaderOfNthVolNode(int Number)
{
struct MinList *titleheader = NULL;
struct VolNode *voln = NULL;
int IsNumber = 0;
voln = (struct VolNode *)Header.mlh_Head;
for(;IsNumber < Number;IsNumber++)
{
voln = (struct VolNode *)voln->ExecNode.ln_Succ;
}
titleheader=&voln->TitleHeader;
if((struct MinList *)titleheader->mlh_TailPred == titleheader)
{
titleheader = NULL;
}
return(titleheader);
}
/* Suche StringB in StringA, gebe Byte des Fundes zurück oder 0. Sucht maximal 5000 Bytes lang! */
/* Gibt Erfolgsmeldung in der Struktur, wenn Kreuz zeigt Position 1 hinter Kreuz! */
void FindStr(char *StringA,char *StringB,struct FindPara *result)
{
LONG ret = 0;
while(ret < 5000)
{
if(StringA[ret]=='#')
{
result->Success = CROSSFOUND;
result->Position = ret+1;
return;
}
if(StringA[ret]==StringB[0])
{
if(CompareFrag(&StringA[ret],StringB)==TRUE)
{
result->Position = ret;
result->Success = STRINGFOUND;
return;
}
}
ret++;
}
result->Success = NOTHINGFOUND;
return;
}
/* Überprüft, ob Frag der Anfang von Text ist. (Bsp: Te in Test, nicht aber Te in DerTest) */
int CompareFrag(char *Text,char *Frag)
{
LONG cnt = 0;
while(Frag[cnt] != 0)
{
if(Frag[cnt]!=Text[cnt])
{
return(FALSE);
}
cnt++;
}
return(TRUE);
}
/* gibt nur ne Meldung aus ;) */
void ShowMsg(STRPTR msg)
{
PutStr(msg);
}
/* durchsucht die liste, gibt selbsttaetig Erfolgsmeldung */
void Search(int task,char * texttofind)
{
static struct VolNode * currentvol;
static struct VolNode * lastfoundvol;
static int volnodecounter, nodecounter;
static struct Node * currentnode;
static char patternbuf[SEARCHLEN*2+2];
if(ParsePatternNoCase(texttofind,patternbuf,SEARCHLEN*2+2) == -1)
{
return;
}
switch(task)
{
case INIT:
volnodecounter = 0;
nodecounter = 0;
currentnode = NULL;
currentvol = (struct VolNode *)Header.mlh_Head;
lastfoundvol = NULL;
return;
break;
case CONTINUE:
lastfoundvol = currentvol;
break;
case FROMTOP:
currentnode = 0;
lastfoundvol = 0;
currentvol = (struct VolNode *)Header.mlh_Head;
volnodecounter = 0;
nodecounter = 0;
break;
}
while(currentvol != (struct VolNode *)&Header.mlh_Tail)
{
/* Volumes scannen */
if((MatchPatternNoCase(patternbuf,(char *)(currentvol+1))!=NULL) && (lastfoundvol != currentvol))
{
SearchMessage((char *)(currentvol+1),"---");
return;
}
if(currentvol->TitleHeader.mlh_TailPred != (struct MinNode *)¤tvol->TitleHeader)
{
/* Titeleintraege scannen */
if(currentnode == 0)
{
currentnode = (struct Node *)currentvol->TitleHeader.mlh_Head;
}
while(currentnode != (struct Node *)¤tvol->TitleHeader.mlh_Tail)
{
if(MatchPatternNoCase(patternbuf,(char*)(currentnode+1))!=NULL)
{
SearchMessage((char *)(currentvol+1),(char *)(currentnode+1));
currentnode = currentnode->ln_Succ;
nodecounter++;
return;
}
nodecounter++;
currentnode = currentnode->ln_Succ;
}
currentnode = 0;
nodecounter = 0;
volnodecounter++;
}
currentvol = (struct VolNode *)currentvol->ExecNode.ln_Succ;
}
DisplayBeep(mywindow->WScreen);
}
void SearchMessage(char * voltext,char * nodetext)
{
static struct EasyStruct myeasystruct = {
sizeof(struct EasyStruct),0,0,"%s: %s\n%s: %s","OK"
};
static char * myarglist[4];
myeasystruct.es_Title = (UBYTE *)Kommandoparameter[4];
myarglist[0] = (char *)Kommandoparameter[1];
myarglist[1] = voltext;
myarglist[2] = (char *)Kommandoparameter[2];
myarglist[3] = nodetext;
EasyRequestArgs(mywindow,&myeasystruct,NULL,myarglist);
}